package com.yunbiao.ybbusstopplate.serialport.agreement;

import android.text.TextUtils;
import com.blankj.utilcode.util.FileUtils;
import com.daimajia.androidanimations.library.bouncing_entrances.BounceInRightAnimator;
import com.yunbiao.ybbusstopplate.bean.SiteInfoBean;
import com.yunbiao.ybbusstopplate.utils.BytesUtils;
import com.yunbiao.ybbusstopplate.utils.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;

/**
 * 通卡通信协议解析
 */
public class TKPortAgreement extends BaseAgreement {
    private static TKPortAgreement tkPortAgreement;

    private final String cmd_up_sites = "21";//上行数据
    private final String cmd_down_sites = "22";//下行数据
    private final String cmd_set_time = "01";//时间
    private final String cmd_site_line = "31";//线路名、终点站、起始站
    private final String cmd_up_down_state = "02";//上下行标识
    private final String cmd_site_state = "03";//站点类型(首站、终站、中站)
    private final String cmd_arr_state = "04";//到离站标识
    private final String cmd_site_index = "05";//站序号
    private final String cmd_site_name = "08";//站名称
    private final String cmd_site_number = "0a";//站点信息
    private final String cmd_info_add = "a0";//透传信息

    private TKPortAgreement() {
    }

    public static TKPortAgreement getInstance() {
        if (tkPortAgreement == null) {
            tkPortAgreement = new TKPortAgreement();
        }
        return tkPortAgreement;
    }

    private StringBuilder hexString = null;
    private String device = "";
    /**
     * 串口数据解析
     *
     * @param bytes
     */
    public synchronized void analysisData(byte[] bytes) {
        if (bytes == null || bytes.length <= 0) {
            return;
        }
        if (hexString == null) {
            hexString = new StringBuilder();
        }

        byte start = bytes[0];
        String startHex = BytesUtils.byteToHex(start);

        byte end = bytes[bytes.length - 1];
        String endHex = BytesUtils.byteToHex(end);

        //开始
        if ("bb".equals(startHex)) {
//            Log.d(TAG, "-----------start---------");
            hexString.delete(0, hexString.length());
            device = BytesUtils.byteToHex(bytes[1]);
        }
        //存储数据
        hexString.append(BytesUtils.bytesToHex(bytes));
        //结束
        if ("55".equals(endHex)) {
//            Log.d(TAG, "-----------end---------");
//            Log.d(TAG, "--->" + hexString.toString());
            String splitStr = "bb" + device;
            String[] hexArray = hexString.toString().split(splitStr);
            for (String ss : hexArray) {
                if (ss != null && !"".equals(ss)) {
//                    System.out.println("bb10" + ss);
                    byte[] byteArray = BytesUtils.hexToByteArray(splitStr + ss);
                    analayzData(byteArray);
                }
            }
        }
    }

    public void analayzData(byte[] data) {
        if (data == null || data.length <= 0) {
            if (agreementListener != null) {
                agreementListener.agreementFailed();
            }
            return;
        }
        try {
            String startHex = BytesUtils.byteToHex(data[0]);
            String endHex = BytesUtils.byteToHex(data[data.length-1]);

            if (TextUtils.isEmpty(startHex) || TextUtils.isEmpty(endHex) || !"bb".equals(startHex) || !"55".equals(endHex)) {
                if (agreementListener != null) {
                    agreementListener.agreementFailed();
                }
                return;
            }

            byte cmd = data[8];//第一个命令符
            String cmdhex = BytesUtils.byteToHex(cmd);
            switch (cmdhex) {
                //站点信息（上行31|下行32）
                case cmd_site_number:
                    break;
                //站点数据
                case cmd_down_sites:
                case cmd_up_sites:
                    getSiteList(data);
                    break;
                //线路名、终点站、起始站
                case cmd_site_line:
                    try {
                        getLineInfo(data);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    break;
                    //到站、离站
                case cmd_up_down_state:
                    getA_LInfo(data);
                    break;
                case cmd_info_add:
                    getSiteTime(data);
                    break;
            }
        } catch (Exception e) {
            e.printStackTrace();
            if (agreementListener != null) {
                agreementListener.agreementFailed();
            }
        }
    }

    public void test() {
        List<Byte> byteList = new ArrayList<>();
        String hex = "E98391E5AEB6EFBC88E7A75E9BE58AA8E585ACE58FB8EFBC89";
        byte[] subData = BytesUtils.hexToByteArray(hex);

//        byte[] subBytes = new byte[subData.length];
        for (int i = 0; i < subData.length; i++) {
            byte subByte = subData[i];
//            subBytes[i]=subByte;
            //转义解析
            if (subByte == 0x5E) {
                i = i + 1;
                byte subDatum = subData[i];
                byte ss = (byte) (subDatum ^ 0x20);
                byteList.add(ss);
            } else {
                byteList.add(subByte);
            }
        }

        byte[] bytes = new byte[byteList.size()];
        for (int i = 0; i < byteList.size(); i++) {
            bytes[i] = byteList.get(i);
        }
        String hex1 = BytesUtils.bytesToHex(bytes);

        String s = StringUtils.hexStringToString(hex1, "utf-8");
        System.out.println(s);
    }

    /**
     * 获取首末班时间
     */
    public void getSiteTime(byte[] data){
        //数据转义
        byte[] esData = escape(data);
        byte[] subByte = BytesUtils.SubByte(esData, 11, esData.length - 13);
        String hex = BytesUtils.bytesToHex(subByte);
        System.out.println(hex);
        String s = StringUtils.hexStringToString(hex);
        System.out.println(s);
        //01=tjtk,02=99999,05=06:00,06=18:00,07=06:10,08=18:10,0D=208,10=1
        if (s!=null&&!"".equals(s)){
            String sTime1="";
            String eTime1="";
            String sTime2="";
            String eTime2="";
            String[] infos = s.split(",");
            for (String ss:infos) {
                if (ss!=null&&!"".equals(ss)){
                    String[] tempInfo = ss.split("=");
                    String key=tempInfo[0];
                    String value=tempInfo[1];
                    switch (key){
                        case "05":
                            sTime1=value;
                            break;
                        case "06":
                            eTime1=value;
                            break;
                        case "07":
                            sTime2=value;
                            break;
                        case "08":
                            eTime2=value;
                            break;
                    }
                }
            }

            System.out.println("s1->"+sTime1+",e1->"+eTime1+";s2->"+sTime2+".e2->"+eTime2);
            if (agreementListener!=null){
//                agreementListener.onSiteTimeResult(sTime1,eTime1,sTime2,eTime2);
                agreementListener.onSiteTimeResult(sTime2,eTime2,sTime1,eTime1);
            }

        }
    }

    /**
     * 获取上、下站点信息
     */
    private ArrayList<String> upSites;
    private ArrayList<String> downSites;
    private static boolean updateSites = false;

    public void getSiteList(byte[] data) {
        updateSites = false;
        if (upSites == null) {
            upSites = new ArrayList<>();
        }
        if (downSites == null) {
            downSites = new ArrayList<>();
        }
        //数据转义
        byte[] esData = escape(data);
        //第一个命令符
        byte cmd = esData[8];
        String cmdhex = BytesUtils.byteToHex(cmd);
        //获取语种数
        String lgHex = BytesUtils.byteToHex(esData[11]);
        Integer lg = Integer.valueOf(lgHex, 16);

        byte[] subBytes = BytesUtils.SubByte(esData, 12, esData.length - 14);

//        //第一个命令符
//        byte cmd = data[8];
//        String cmdhex = BytesUtils.byteToHex(cmd);
//        //获取语种数
//        String lgHex = BytesUtils.byteToHex(data[11]);
//        Integer lg = Integer.valueOf(lgHex, 16);
//
//        byte[] subData = BytesUtils.SubByte(data, 12, data.length - 14);

//        数据转义
//        byte[] subBytes = escape(subData);

        System.out.println("subBytes: " + BytesUtils.bytesToHex(subBytes));
        System.out.println("cmd: " + cmdhex);

        if (cmd_up_sites.equals(cmdhex)){//上行数据
            upSites.clear();
        }else {
            downSites.clear();
        }

        for (int i = 0; i < subBytes.length; i++) {
            //获取序号
            byte[] index = new byte[2];
            index[0] = subBytes[i];
            i = i + 1;
            index[1] = subBytes[i];
            String indexHex = BytesUtils.bytesToHex(index);
            Integer number = Integer.valueOf(indexHex, 16);
            //获取站名长度
            i = i + 1;
            byte length = subBytes[i];
            Integer lt = Integer.valueOf(BytesUtils.byteToHex(length), 16);
            //获取站点名字
            byte[] nameBytes = new byte[lt];
            for (int j = 0; j < lt; j++) {
                i = i + 1;
                nameBytes[j] = subBytes[i];
            }
            //跳过语种。00
            for (int j = 0; j < lg - 1; j++) {
                i = i + 1;
            }

            String nameHex = BytesUtils.bytesToHex(nameBytes);
            String name = StringUtils.hexStringToString(nameHex, "utf-8");

//            System.out.println("num:" + number + " ,hex:" + nameHex + ", name:" + name);

            if (cmd_up_sites.equals(cmdhex)) {
                upSites.add(name);//上行数据
            } else {
                downSites.add(name);
            }
        }
        updateSites = true;
    }

    //数据转义
    public byte[] escape(byte[] subData) {
        //数据转义
        List<Byte> byteList = new ArrayList<>();
//        for (int i = 0; i < subData.length; i++) {
//            byte subByte = subData[i];
//            //转义解析
//            if (i < subData.length-2 && subByte == 0x5E) {
//                byteList.add(subByte);
//                i = i + 1;
//                byte subDatum = subData[i];
//                byte ss = (byte) (subDatum ^ 0x20);
//                byteList.add(ss);
//            } else {
//                byteList.add(subByte);
//            }
//        }
        for (int i = 0; i < subData.length; i++) {
            byte subByte = subData[i];
            if (subByte == 0x5E) {
                i = i + 1;
                byte subDatum = subData[i];
                byte ss = (byte) (subDatum ^ 0x20);
                byteList.add(ss);
            } else {
                byteList.add(subByte);
            }
        }
        byte[] subBytes = new byte[byteList.size()];
        for (int i = 0; i < byteList.size(); i++) {
            subBytes[i] = byteList.get(i);
        }
        return subBytes;
    }

    /**
     * 获取线路名、起始站、终点站
     *
     * @param data
     */
    private boolean isUpDataLineInfo=false;
    public void getLineInfo(byte[] data) {
        isUpDataLineInfo=false;

        String lineName = "", startName = "", endName = "";

        //转义字符
        byte[] escapeData = escape(data);
        byte[] subByte = BytesUtils.SubByte(escapeData, 8, escapeData.length - 10);
        byte[] escapeBytes=subByte;

//        byte[] subByte = BytesUtils.SubByte(data, 8, data.length - 10);
//        //转义字符
//        byte[] escapeBytes = escape(subByte);

        for (int i = 0; i < escapeBytes.length; i++) {
            //标识符
            byte cmd = escapeBytes[i];
            String cmdHex = BytesUtils.byteToHex(cmd);
            //数据总长度
            byte[] allLength = new byte[2];
            for (int j = 0; j < allLength.length; j++) {
                i = i + 1;
                allLength[j] = escapeBytes[i];
            }
            //语种数量
            i = i + 1;
            byte lgByte = escapeBytes[i];
            Integer lgNum = Integer.valueOf(BytesUtils.byteToHex(lgByte), 16);
            //name长度
            i = i + 1;
            byte nameLength = escapeBytes[i];
            Integer lt = Integer.valueOf(BytesUtils.byteToHex(nameLength), 16);
            byte[] nameBytes = new byte[lt];
            for (int j = 0; j < lt; j++) {
                i = i + 1;
                nameBytes[j] = subByte[i];
            }
            String nameHex = BytesUtils.bytesToHex(nameBytes);
            String name = StringUtils.hexStringToString(nameHex, "utf-8");
            //语种排除 00
            for (int j = 0; j < lgNum - 1; j++) {
                i = i + 1;
            }

            if (cmd_site_line.equals(cmdHex)) {
                //线路名
                lineName = name;
            } else if ("32".equals(cmdHex)) {
                //起始站
                startName = name;
            } else if ("33".equals(cmdHex)) {
                //终点站
                endName = name;
            }
        }

        System.out.println("line: " + lineName + " ,start: " + startName + ", endName: " + endName);
        if (agreementListener!=null){
            String[] lineArray = new String[3];
            lineArray[0]=lineName;
            lineArray[1]=startName;
            lineArray[2]=endName;

            if ((upSites!=null&&upSites.size()>0)&&(downSites!=null&&downSites.size()>0)){
                //更新线路号
                isUpDataLineInfo=true;
                agreementListener.onLineInfoResult(lineArray);
                String s = upSites.get(0);
                //更新列表
                if (s.equals(startName)){
                    agreementListener.onSiteListResult(upSites);
                }else {
                    agreementListener.onSiteListResult(downSites);
                }
            }
        }
    }

    /**
     * 获取 上下行 到站离站信息
     *
     * @param data
     */
    private int siteType;//上下行数据
    public void getA_LInfo(byte[] data) {
        byte[] escapeData = escape(data);
        byte[] subByte = BytesUtils.SubByte(escapeData, 8, escapeData.length - 10);
        byte[] subData=subByte;

//        byte[] subByte = BytesUtils.SubByte(data, 8, data.length - 10);
//        byte[] subData = escape(subByte);

//        List<String> list=new ArrayList<>();
//        list.subList(list.indexOf(""))

        String type = "", alType = "", position = "", sName = "";

        for (int i = 0; i < subData.length; i++) {
            //标识符
            byte cmd = subData[i];
            String cmdHex = BytesUtils.byteToHex(cmd);

            if ("02".equals(cmdHex)) {
                //上下行标识
                byte[] length = new byte[2];
                for (int j = 0; j < length.length; j++) {
                    i = i + 1;
                    length[j] = subData[i];
                }
                Integer dLength = Integer.valueOf(BytesUtils.bytesToHex(length), 16);
                byte[] typeBytes = new byte[dLength];
                for (int j = 0; j < dLength; j++) {
                    i = i + 1;
                    typeBytes[j] = subData[i];
                }
                String typehex = BytesUtils.bytesToHex(typeBytes);

                type = typehex;

            } else if ("03".equals(cmdHex)) {
                byte[] length = new byte[2];
                for (int j = 0; j < length.length; j++) {
                    i = i + 1;
                    length[j] = subData[i];
                }
                Integer dLength = Integer.valueOf(BytesUtils.bytesToHex(length), 16);
                byte[] typeBytes = new byte[dLength];
                for (int j = 0; j < dLength; j++) {
                    i = i + 1;
                    typeBytes[j] = subData[i];
                }
                String typehex = BytesUtils.bytesToHex(typeBytes);
            } else if ("04".equals(cmdHex)) {
                //到、离站标识
                byte[] length = new byte[2];
                for (int j = 0; j < length.length; j++) {
                    i = i + 1;
                    length[j] = subData[i];
                }
                Integer dLength = Integer.valueOf(BytesUtils.bytesToHex(length), 16);
                byte[] typeBytes = new byte[dLength];
                for (int j = 0; j < dLength; j++) {
                    i = i + 1;
                    typeBytes[j] = subData[i];
                }
                String typehex = BytesUtils.bytesToHex(typeBytes);
                alType = typehex;
            } else if ("05".equals(cmdHex)) {
                //站序号
                byte[] length = new byte[2];
                for (int j = 0; j < length.length; j++) {
                    i = i + 1;
                    length[j] = subData[i];
                }
                Integer dLength = Integer.valueOf(BytesUtils.bytesToHex(length), 16);
                byte[] typeBytes = new byte[dLength];
                for (int j = 0; j < dLength; j++) {
                    i = i + 1;
                    typeBytes[j] = subData[i];
                }
                String typehex = BytesUtils.bytesToHex(typeBytes);
                Integer index = Integer.valueOf(typehex, 16);
                position = index + "";
            } else if ("08".equals(cmdHex)) {
                //站标识
                byte[] length = new byte[2];
                for (int j = 0; j < length.length; j++) {
                    i = i + 1;
                    length[j] = subData[i];
                }
                Integer dLength = Integer.valueOf(BytesUtils.bytesToHex(length), 16);
                //类型
                i = i + 1;
                dLength = dLength - 1;
                byte typeBytes = subData[i];
                //序号
                byte[] index = new byte[2];
                for (int j = 0; j < index.length; j++) {
                    i = i + 1;
                    dLength = dLength - 1;
                    index[j] = subData[i];
                }

                byte[] name = new byte[dLength];
                for (int j = 0; j < dLength; j++) {
                    i = i + 1;
                    name[j] = subData[i];
                }
                String nameDex = BytesUtils.bytesToHex(name);
                String siteName = StringUtils.hexStringToString(nameDex, "utf-8");
                sName = siteName;
            }
        }

        //type 2:下行  1：上行  altype：1：到站 2：下一站
        System.out.println("type:" + type + " ,alType:" + alType + " index:" + position + " name:" + sName);
        //返回站点列表
        if (updateSites){
            updateSites=false;
//            if (agreementListener!=null){
//                if ("01".equals(type)){
//                    siteType=1;
//                    agreementListener.onSiteListResult(upSites);
//                }else {
//                    siteType=2;
//                    agreementListener.onSiteListResult(downSites);
//                }
//            }
        }

        //返回提示信息
        if (agreementListener!=null){
            SiteInfoBean siteInfoBean = new SiteInfoBean();
            if ("01".equals(alType)){
                siteInfoBean.setStutas(1);
            }else {
                siteInfoBean.setStutas(0);
            }
            siteInfoBean.setSiteName(sName);
            siteInfoBean.setShowTime(10);
            agreementListener.onSiteTipResult(siteInfoBean);
        }
    }
}
